﻿using System;
using Wizard.Compiler.Parsers;
using Wizard.Runtime;

namespace Wizard.Functions
{
    internal class BitwizeOperator : TwoParams<int, int, int>
    {
        private readonly RecalcDelegate mRecalcDelegate;

        public BitwizeOperator(IHasValue<int> param1, TokenType tt, IHasValue<int> param2)
            : base("BitwizeOp", FunctionType.@operator, param1, param2)
        {
            if (tt == TokenType.operator_or)
            {
                mRecalcDelegate = Or;
            }
            else if (tt == TokenType.operator_and)
            {
                mRecalcDelegate = And;
            }
            //else if (tt == eTokenType.operator_xor)
            //{
            //    mRecalcDelegate = Xor;
            //}
            else
            {
                throw new Exception("Invalid BinaryOp " + tt);
            }
        }

        protected override int RecalcValue(IRunContext context)
        {
            return mRecalcDelegate(context);
        }

        private int Or(IRunContext context)
        {
            return mParam1.Value(context) | mParam2.Value(context);
        }

        private int And(IRunContext context)
        {
            return mParam1.Value(context) & mParam2.Value(context);
        }

        private int Xor(IRunContext context)
        {
            return mParam1.Value(context) ^ mParam2.Value(context);
        }

        #region Nested type: RecalcDelegate

        private delegate int RecalcDelegate(IRunContext context);

        #endregion
    }
}